// FILE: Chip8RAM.h by Richard Hughes 27/04/2012
//
// DESC: Defines Chip8 RAM

#ifndef __chip8ram_h__
#define __chip8ram_h__

// INCLUDES
#include <memory>
#include <assert.h>
#include "IRAM.h"

// DEFINES
#define SMALL_FONT_START_ADDRESS 0x0
#define BASE_WRITABLE 0x200
#define MAX_WRITABLE 0xFFF

// NAMESPACES
namespace Emulator
{
namespace Chip8
{

/*************************************************************/
//
// CLASS: Chip8RAM
//
// DESC: Defines Chip8 RAM
//
/*************************************************************/

class Chip8RAM : public IRAM
{
private:

	address _baseWritable;
	address _maxWritable;

	address _smallFontStartAddress;

	byte _memory[MAX_WRITABLE];

	void SetFontInMemory();

public:

	Chip8RAM()
	{
		this->_baseWritable = BASE_WRITABLE;
		this->_maxWritable = MAX_WRITABLE;
		this->_smallFontStartAddress = SMALL_FONT_START_ADDRESS;

		this->Reset();
	}
	~Chip8RAM()
	{
		this->Reset();
	}

	void Reset();

	inline byte Read(address ad) const
	{
		assert(ad >= this->GetFontStartAddress() && ad <= this->GetMaxWritable());
		return this->_memory[ad];
	}

	inline void ReadBytes(uint8_t* dest, address ad, uint8_t count)
	{
		assert(ad >= this->GetFontStartAddress() && ad <= this->GetMaxWritable());
		for(int i = 0; i < count; i++)
		{
			dest[i] = this->_memory[ad + i];
		}
	}

	inline uint16_t Read16Bit(address ad) const
	{
		assert(ad >= this->GetFontStartAddress() && ad <= this->GetMaxWritable());
		return this->_memory[ad] << 8 | this->_memory[ad + 1];
	}

	inline void Write(address ad, byte value)
	{
		assert(ad >= this->GetBaseWritable() && ad <= this->GetMaxWritable());
		this->_memory[ad] = value;
	}

	inline void Write(byte* ads, address start, int length)
	{
		memcpy(this->_memory + start, ads, length);
	}

	inline address const GetBaseWritable() const
	{
		return this->_baseWritable;
	}

	inline address const GetMaxWritable() const
	{
		return this->_maxWritable;
	}

	inline address const GetFontStartAddress(bool small = true) const
	{
		return small ? this->_smallFontStartAddress : 0;
	}

}; // Chip8

} // Chip8
} // Emulator

#endif // __chip8ram_h__

// EOF: IRaM.h